import React, { useEffect, useRef, useCallback, useState } from 'react';
import type { ReactNode } from 'react';
import classNames from 'classnames';
import { CheckOutlined } from '@ant-design/icons';
import './index.less';

interface DataItem {
  [x: string]: any;
  label: string;
  key: string;
}

const DropDownRender: React.FC<{
  extra?: string | ((item: DataItem) => string);
  value: string[];
  data: DataItem[];
  onItemClick: (item: DataItem, checked: boolean) => void;
  iconRender?: (item: DataItem) => ReactNode;
  emptyRender?: () => ReactNode;
  searchValue: string;
}> = (props) => {
  const scrollRef = useRef(null);
  const [focusIndex, _focusIndex] = useState(-1);
  const { data, extra, value, iconRender, emptyRender, searchValue } = props;
  const getExtra = useCallback(
    (item: DataItem) => (extra ? (typeof extra == 'function' ? extra(item) : item[extra]) : null),
    [extra],
  );

  const renderLabel = useCallback(
    (label: string, rowIndex: number) => {
      if (label) {
        const index = label.toLowerCase().indexOf(searchValue.toLowerCase());
        if (index > -1) {
          const arr = [
            label.slice(0, index),
            label.slice(index, index + searchValue.length),
            label.slice(index + searchValue.length),
          ];
          return (
            <span>
              {arr.map((item, i) => (
                <span
                  key={`label-${rowIndex}-${i}`}
                  style={i == 1 ? { color: 'var(--inbiz-color-primary)' } : {}}
                >
                  {item}
                </span>
              ))}
            </span>
          );
        }
        return <span>{label}</span>;
      }
    },
    [searchValue],
  );

  const renderItem = useCallback(
    (item: DataItem, index: number) => {
      if (item) {
        const isActive = (value || []).indexOf(item.Id) > -1;
        return (
          <div
            key={item.Id}
            className={classNames('inbiz-EformMemberSelect-DropdownItem', {
              active: isActive,
              isFocus: focusIndex == index,
            })}
            onClick={(e) => {
              props.onItemClick(item, !isActive);
            }}
            onMouseEnter={(e) => {
              _focusIndex(index);
            }}
          >
            {iconRender?.(item) || null}
            <div title={item.name}>{renderLabel(item.name, index)}</div>
            <div>{getExtra(item)}</div>
            {isActive ? <CheckOutlined /> : null}
          </div>
        );
      }
    },
    [focusIndex, value, getExtra, props.onItemClick, renderLabel],
  );

  const bindKeyboardEvents = useCallback(
    (e: any) => {
      if (e.keyCode == 40) {
        // 下一个
        if (focusIndex < data.length - 1) {
          _focusIndex(focusIndex + 1);
          // scrollRef.current?.scrollTo(0, 40 * (focusIndex + 1));
        }
      } else if (e.keyCode == 38) {
        // 上一个
        if (focusIndex > 0) {
          _focusIndex(focusIndex - 1);
          // scrollRef.current?.scrollTo(0, 40 * (focusIndex - 1));
        }
      } else if (e.keyCode == 13) {
        // Enter
        const item = data[focusIndex];
        if (item) {
          const isActive = (value || []).indexOf(item.key) > -1;
          props.onItemClick(item, !isActive);
        }
      }
    },
    [data, focusIndex, value, scrollRef],
  );

  useEffect(() => {
    _focusIndex(data.length ? 0 : -1);
  }, [data]);

  useEffect(() => {
    document.addEventListener('keydown', bindKeyboardEvents, false);
    return () => {
      document.removeEventListener('keydown', bindKeyboardEvents, false);
    };
  }, [bindKeyboardEvents]);

  return (
    <div
      ref={scrollRef}
      className={classNames('inbiz-EformMemberSelect-Dropdown', {
        'ant-select-dropdown-empty': !data.length,
      })}
    >
      {data.map(renderItem)}
      {/* {data.length ? null : emptyRender?.()} */}
    </div>
  );
};

export default DropDownRender;
